(function(){
var field_game,field_msg,field_mines,field_parent,
		field_level,field_time,btn_restart,unit_size,
		sym_mine='&lowast;',sym_nil='&nbsp;',sym_wrong='&times;',
		levels=[
			{name:'初级',width:10,height:10,mines:10},
			{name:'中级',width:16,height:16,mines:40},
			{name:'高级',width:30,height:16,mines:99},
		],blanks=-1,items,level_data,data,total,level,mines,timer;
function init(){
	field_parent=document.getElementById('mine');
	unit_size=Number(field_parent.getAttribute('data-unit-size'))||21;
	var i=0,b,$=field_parent.querySelector.bind(field_parent);
	b=document.createElement('style');
	b.innerHTML='#game span{width:'+unit_size+'px;height:'+unit_size+'px;line-height:'+unit_size+'px;}';
	document.head.appendChild(b);
	field_parent.innerHTML='\
<label>剩余地雷：<span id=mines>10</span></label>\
<label>已用时间：<span id=time>0</span>s</label>\
<label>级别：<select id=level></select><button id=new>重新开始</button></label>\
<div id=msg></div>\
<div id=game></div>';
	field_game=$('#game');
	field_msg=$('#msg');
	field_mines=$('#mines');
	field_level=$('#level');
	field_time=$('#time');
	btn_restart=$('#new'),
	b=[];
	levels.forEach(function(j){b.push('<option value='+(i++)+'>'+j.name+'</option>');});
	field_level.innerHTML=b.join('');field_level.value=0;
	btn_restart.onclick=field_level.onchange=restart;
	field_game.onclick=field_game.oncontextmenu=function(e){
		e.preventDefault();
		if(blanks) {
			var i=items.indexOf(e.target);
			if(i>=0) click(i,e.type);
		}
	};
	restart();
}
function getPos(i){
	var p={};
	p.top=2+Math.floor(i/level_data.width)*(unit_size+4);
	p.left=2+i%level_data.width*(unit_size+4);
	return p;
}
function newGame(c){
	function update(n) {
		data[n].num++;
		if(n%d.width) data[n-1].num++;
		if((n+1)%d.width) data[n+1].num++;
	}
	var d=level_data,a=d.mines,l=total-1,i,j;
	blanks=total-d.mines;
	data=[];
	for(i=0;i<total;i++) {
		j={mine:i!=c&&a/l>Math.random(),num:0};
		data.push(j);if(j.mine) a--;if(i!=c) l--;
	}
	for(i=0;i<total;i++) if(data[i].mine) {
		if(i>=d.width) update(i-d.width);
		update(i);
		if(i+d.width<total) update(i+d.width);
	}
	field_msg.innerHTML='开始了，小心一点！';count(1);
}
function restart(e){
	var b=[],i,j,g=field_game,d;
	level=field_level.value;
	d=level_data=levels[level];
	total=d.width*d.height;
	for(i=0;i<total;i++) b.push('<span>'+sym_nil+'</span>');
	g.innerHTML=b.join('');
	g.style.maxWidth=(unit_size+4)*d.width+4+'px';
	g.style.height=(unit_size+4)*d.height+4+'px';
	items=[];
	for(i=0;i<total;i++) {
		b=g.childNodes[i];j=getPos(i);
		b.style.top=j.top+'px';
		b.style.left=j.left+'px';
		items.push(b);
	}
	field_mines.innerHTML=mines=d.mines;
	field_msg.innerHTML='准备开始吧...';
	if(e) field_parent.scrollIntoView();
	blanks=-1;count(-1);
}
function count(f){
	if(timer) {
		clearInterval(timer);
		timer=null;
	}
	var time;
	if(f<0) field_time.innerHTML=time=0;
	else if(f) {
		time=0;
		timer=setInterval(function(){
			field_time.innerHTML=++time;
		},1000);
	}
}
function validate(i){
	function check(n) {
		if(!data[n].mine&&data[n].marked) wrong=1;
		return !data[n].mine^data[n].marked;
	}
	function rcheck(n) {
		var r=check(n);
		if(n%width) r&=check(n-1);
		if((n+1)%width) r&=check(n+1);
		return r;
	}
	var width=level_data.width,wrong=0,r=0;
	if(data[i].open) {
		r=rcheck(i);
		if(i>=width) r&=rcheck(i-width);
		if(i+width<total) r&=rcheck(i+width);
		if(wrong) lose(-1);
	}
	return r;
}
function spread(i){
	function _spread(n) {
			open(n);
			if(n%width) open(n-1);
			if((n+1)%width) open(n+1);
	}
	var width=level_data.width;
	if(i>=width) _spread(i-width);
	_spread(i);
	if(i+width<total) _spread(i+width);
}
function spark(i){
	function _spark(n) {
		if(!data[n].open&&!data[n].marked) items[n].classList.toggle('spark');
	}
	function rspark(n) {
		if(n!=i) _spark(n);
		if(n%width) _spark(n-1);
		if((n+1)%width) _spark(n+1);
	}
	function work() {
		rspark(i);
		if(i>=width) rspark(i-width);
		if(i+width<total) rspark(i+width);
	}
	var width=level_data.width;
	work();setTimeout(work, 200);
}
function open(i){
	if(!data[i].open&&!data[i].marked) {
		if(data[i].mine) lose(i);
		else {
			items[i].className='open';
			data[i].open=1;blanks--;
			if(data[i].num) items[i].innerHTML=data[i].num; else spread(i);
			if(!blanks) {
				field_msg.innerHTML='你赢了！';
				for(i=0;i<total;i++) if(data[i].mine&&!data[i].marked) items[i].innerHTML=sym_mine;
				count();field_mines.innerHTML=0;
			}
		}
	}
}
function click(i,e){
	switch(e) {
	case 'click':
		if(blanks<0) newGame(i);
		if(data[i].open) {
			if(validate(i)) spread(i);
			else spark(i);
		} else open(i);
		break;
	case 'contextmenu':
		if(!data[i].open) {
			if(data[i].marked=!data[i].marked) {
				items[i].innerHTML=sym_mine;
				field_mines.innerHTML=--mines;
			} else {
				items[i].innerHTML=sym_nil;
				field_mines.innerHTML=++mines;
			}
		}
		break;
	}
}
function lose(e){
	var i;
	if(e>=0) {i=items[e];i.className='wrong';i.innerHTML=sym_wrong;}
	blanks=0;field_msg.innerHTML='你输了！';count();
	for(i=0;i<total;i++)
		if(!data[i].mine&&data[i].marked) {items[i].className='wrong';items[i].innerHTML=sym_wrong;}
		else if(data[i].mine&&!data[i].marked) items[i].innerHTML=sym_mine;
}
init();
})();
